﻿/******************************************************************
 Copyright (C) 2017 - All Rights Reserved by
 文 件 名 : qtvideowidgetsurface.cpp --- QtVideoWidgetSurface
 作 者    : Niyh  (QQ:393320854)
 编写日期 : 2019
 说 明    :
 历史纪录 :
 <作者>    <日期>        <版本>        <内容>
           2019/9/22
 码农爱学习  2023/2/19               修改整理
*******************************************************************/
#include "qtvideowidgetsurface.h"

#include <QPainter>
#include <QPaintEvent>
#include <QDebug>

QtVideoWidgetSurface::QtVideoWidgetSurface(QWidget *widget, QObject *parent)
    : QAbstractVideoSurface(parent), widget(widget), imageFormat(QImage::Format_Invalid)
{
}

//! [0] 该函数用于向Qt返回帧流的图像类型
QList<QVideoFrame::PixelFormat> QtVideoWidgetSurface::supportedPixelFormats(
    QAbstractVideoBuffer::HandleType handleType) const
{
    if (handleType == QAbstractVideoBuffer::NoHandle)
    {
        return QList<QVideoFrame::PixelFormat>()
               << QVideoFrame::Format_RGB32
               << QVideoFrame::Format_ARGB32
               << QVideoFrame::Format_ARGB32_Premultiplied
               << QVideoFrame::Format_RGB565
               << QVideoFrame::Format_RGB555;
    }
    else
    {
        return QList<QVideoFrame::PixelFormat>();
    }
}
//! [0]

//! [1]
bool QtVideoWidgetSurface::isFormatSupported(const QVideoSurfaceFormat &format) const
{
    const QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat());
    const QSize size = format.frameSize();

    return imageFormat != QImage::Format_Invalid && !size.isEmpty() && format.handleType() == QAbstractVideoBuffer::NoHandle;
}
//! [1]

//! [2]
bool QtVideoWidgetSurface::start(const QVideoSurfaceFormat &format)
{
    const QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat());
    const QSize size = format.frameSize();

    if (imageFormat != QImage::Format_Invalid && !size.isEmpty())
    {
        this->imageFormat = imageFormat;
        imageSize = size;
        sourceRect = format.viewport();

        QAbstractVideoSurface::start(format);

        widget->updateGeometry();
        updateVideoRect();

        return true;
    }
    else
    {
        return false;
    }
}
//! [2]

//! [3]
void QtVideoWidgetSurface::stop()
{
    currentFrame = QVideoFrame();
    targetRect = QRect();

    QAbstractVideoSurface::stop();

    widget->update();
}
//! [3]

//! [4] 该函数用于获取到每一帧
bool QtVideoWidgetSurface::present(const QVideoFrame &frame)
{
    if (surfaceFormat().pixelFormat() != frame.pixelFormat() || surfaceFormat().frameSize() != frame.size())
    {
        setError(IncorrectFormatError);
        stop();

        return false;
    }
    else
    {
        currentFrame = frame;

        widget->repaint(targetRect);

        return true;
    }
}
//! [4]

//! [5]
void QtVideoWidgetSurface::updateVideoRect()
{
    //    QSize size = surfaceFormat().sizeHint();
    //    size.scale(widget->size(), Qt::KeepAspectRatio);

    targetRect = QRect(QPoint(0, 0), widget->size());
    //    targetRect.moveCenter(widget->rect().center());
}
//! [5]

//! [6]
void QtVideoWidgetSurface::paint(QPainter *painter)
{
    if (currentFrame.map(QAbstractVideoBuffer::ReadOnly))
    {
        const QTransform oldTransform = painter->transform();

        if (surfaceFormat().scanLineDirection() == QVideoSurfaceFormat::BottomToTop)
        {
            painter->scale(1, -1);
            painter->translate(0, -widget->height());
        }

        QImage image(
            currentFrame.bits(),
            currentFrame.width(),
            currentFrame.height(),
            currentFrame.bytesPerLine(),
            imageFormat);

        painter->drawImage(targetRect, image, sourceRect);

        painter->setTransform(oldTransform);

        currentFrame.unmap();
    }
}
//! [6]
